Shader "Custom/BloomPostProcess" // 使用 Hidden/ 前缀使其不显示在材质创建菜单中
{
    Properties
    {
        _MainTex ("Source Texture", 2D) = "white" {} // 输入纹理
        _BloomSize ("Bloom Size", Range(0.0, 0.1)) = 0.01
        _BloomIntensity ("Bloom Intensity", Range(0.0, 5.0)) = 1.0
        _BloomThreshold ("Bloom Threshold", Range(0.0, 1.0)) = 0.4
        _BloomGamma ("Bloom Gamma", Range(1.0, 3.0)) = 2.0
    }

    SubShader
    {
        // 不需要剔除或深度测试
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS   : POSITION;
                float2 uv           : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionCS   : SV_POSITION;
                float2 uv           : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_TexelSize; // Unity 自动提供纹理像素大小 (1/width, 1/height, width, height)

            CBUFFER_START(UnityPerMaterial)
                float _BloomSize;
                float _BloomIntensity;
                float _BloomThreshold;
                float _BloomGamma;
            CBUFFER_END

            Varyings vert(Attributes input)
            {
                Varyings output;
                // 对于全屏后处理，直接使用顶点位置
                output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
                // UV 通常由 Blit 操作处理，但我们也可以手动计算
                output.uv = input.uv;
                return output;
            }

            // 横向模糊/辉光函数 (现在采样纹理)
            float3 lateral_bloom_tex(float2 uv, float2 direction, float blurSize, float threshold, float gamma)
            {
                const int MAX_TAPS = 16; // 采样次数，影响质量和性能
                float3 accumulatedColor = float3(0,0,0);

                // 计算基于像素的偏移，而不是 UV 百分比
                // blurSize 现在可以理解为模糊半径（以像素为单位，如果需要的话，或者保持 UV 空间）
                // 为了简单起见，我们继续使用 UV 空间的 blurSize，但乘以 TexelSize 来获得像素偏移感
                // float2 pixelDirection = direction * _MainTex_TexelSize.xy * blurSize * 100; // 乘以一个系数调整大小感

                for (int i = 1; i <= MAX_TAPS; ++i)
                {
                    float f = (float)i / (float)MAX_TAPS;
                    float falloff = exp2(-8.0 * f * f); // 衰减

                    // UV 偏移
                    float2 uvOffset = direction * f * blurSize; // 直接在 UV 空间偏移

                    // --- 正方向采样 ---
                    float3 sampleColorPos = tex2D(_MainTex, uv + uvOffset).rgb;
                    sampleColorPos = pow(max(sampleColorPos - threshold, 0.0), gamma);
                    accumulatedColor += sampleColorPos * falloff;

                    // --- 负方向采样 ---
                    float3 sampleColorNeg = tex2D(_MainTex, uv - uvOffset).rgb;
                    sampleColorNeg = pow(max(sampleColorNeg - threshold, 0.0), gamma);
                    accumulatedColor += sampleColorNeg * falloff;
                }
                return accumulatedColor / (float)(MAX_TAPS); // 近似归一化
            }

            
            half4 frag(Varyings input) : SV_Target
            {
                float2 uv = input.uv;

                // 1. 获取原始像素颜色
                float3 baseColor = tex2D(_MainTex, uv).rgb;

                // 2. 计算辉光
                float3 bloomColor = float3(0,0,0);
                if (_BloomIntensity > 0.0 && _BloomSize > 0.0)
                {
                    float2 dir1 = float2(1, 0);
                    float2 dir2 = float2(0.5, 0.866);
                    float2 dir3 = float2(-0.5, 0.866);

                    bloomColor += lateral_bloom_tex(uv, dir1, _BloomSize, _BloomThreshold, _BloomGamma);
                    bloomColor += lateral_bloom_tex(uv, dir2, _BloomSize * 0.8, _BloomThreshold, _BloomGamma);
                    bloomColor += lateral_bloom_tex(uv, dir3, _BloomSize * 0.8, _BloomThreshold, _BloomGamma);
                }

                // 3. 组合颜色 (在 Gamma 空间混合)
                // !! 修改这里：确保 baseColor 不为负数再进行 pow 操作 !!
                float3 combinedColor = pow(max(baseColor, 0.0), _BloomGamma) + bloomColor * _BloomIntensity;

                // 4. 反 Gamma 校正 (这里已经有 max 处理)
                combinedColor = pow(max(combinedColor, 0.0), 1.0 / _BloomGamma);

                return half4(combinedColor, 1.0); // 输出最终颜色
            }
            ENDHLSL
        }
    }
}